<template>
  <div flex="~ col">
    <div>
      <el-form :inline="true" :model="queryForm">
        <el-form-item label="角色名称">
          <el-input v-model="queryForm.roleName" placeholder="请输入角色名称" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <div class="mb-4 flex justify-end">
      <el-button type="primary" @click="handleAdd">新增角色</el-button>
    </div>

    <el-table :data="tableData" border style="width: 100%" height="400">
      <el-table-column fixed prop="roleName" label="角色名称" />
      <el-table-column prop="roleCode" label="角色编码" />
      <el-table-column prop="description" label="角色描述" />
      <el-table-column label="操作" width="320" fixed="right">
        <template #default="{ row }">
          <el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
          <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
          <el-button link type="success" @click="handlePermissionAction(row, 'assign')"
            >绑定权限</el-button
          >
          <el-button link type="warning" @click="handlePermissionAction(row, 'unbind')"
            >解绑权限</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <div class="flex justify-end mt-4">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 角色表单对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'add' ? '新增角色' : '编辑角色'"
      width="500px"
      destroy-on-close
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="form.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="角色编码" prop="roleCode">
          <el-input v-model="form.roleCode" placeholder="请输入角色编码" />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="form.description" type="textarea" placeholder="请输入角色描述" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 权限操作抽屉（合并绑定和解绑） -->
    <el-drawer
      v-model="permissionDrawerVisible"
      :title="permissionAction === 'assign' ? '绑定权限' : '解绑权限'"
      size="600px"
    >
      <div v-loading="permissionLoading">
        <div class="mb-4 flex justify-between items-center">
          <div class="text-sm text-gray-600">
            {{
              permissionAction === 'assign'
                ? '请选择要绑定的权限（支持多选）'
                : '请选择要解绑的权限（支持多选）'
            }}
          </div>
        </div>

        <el-tree
          ref="permissionTreeRef"
          :data="permissionTreeData"
          :props="treeProps"
          show-checkbox
          :default-expand-all="false"
          node-key="id"
          :check-strictly="false"
          :default-checked-keys="defaultCheckedKeys"
          class="permission-tree"
          @check="handlePermissionTreeCheck"
        >
          <template #default="{ node, data }">
            <div 
              class="tree-node-content" 
              :class="{
                'is-disabled': data.disabled,
                'is-bound': data.isBound,
                'is-menu': data.permType === 1,
                'is-button': data.permType === 2
              }"
            >
              <!-- 图标区域 -->
              <div class="node-icon">
                <i 
                  v-if="data.permType === 1" 
                  :class="data.icon || 'el-icon-menu'" 
                  class="menu-icon"
                />
                <i 
                  v-else 
                  class="el-icon-operation button-icon"
                />
              </div>
              
              <!-- 权限名称 -->
              <span class="node-label">{{ data.permName }}</span>
              
              <!-- 状态标签区域 -->
              <div class="node-tags">
                <!-- 权限类型标签 -->
                <el-tag 
                  :type="data.permType === 1 ? 'primary' : 'success'" 
                  size="small" 
                  class="type-tag"
                >
                  {{ data.permType === 1 ? '菜单' : '按钮' }}
                </el-tag>
                
                <!-- 绑定状态标签（简化显示） -->
                <el-tag 
                  v-if="permissionAction === 'assign' && data.isBound"
                  type="info" 
                  size="small" 
                  class="status-tag"
                >
                  已绑定
                </el-tag>
                <el-tag 
                  v-else-if="permissionAction === 'unbind' && !data.isBound"
                  type="info" 
                  size="small" 
                  class="status-tag"
                >
                  未绑定
                </el-tag>
              </div>
            </div>
          </template>
        </el-tree>
      </div>
      <template #footer>
        <div class="flex justify-end gap-2">
          <el-button @click="permissionDrawerVisible = false">取消</el-button>
          <el-button
            :type="permissionAction === 'assign' ? 'primary' : 'danger'"
            @click="handleConfirmPermissionAction"
          >
            {{ permissionAction === 'assign' ? '确定' : '解绑' }}
          </el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance } from 'element-plus'
import {
  createRole,
  createRolePermission,
  getOneRolePermission,
  updateRolePermission,
  deleteRole,
  fetchList,
  getOneRole,
  updateRole,
  deleteRolePermission
} from '@/api/role'
import { fetchList as fetchPermissionList } from '@/api/permission'
import { useUserStore } from '../../../store/user'

const userStore = useUserStore()

// 类型定义
interface RoleItem {
  id?: number
  roleName: string
  roleCode: string
  description: string
}

interface PermissionItem {
  id: number
  permName: string
  permCode: string
  permType: number
  parentId: number
  description: string
  path?: string
  component?: string
  icon?: string
  children?: PermissionItem[]
  hasChildren?: boolean
  isBound?: boolean
  disabled?: boolean
}

interface RolePermissionData {
  id?: number
  roleId: number
  permissionIds: number[]
}

// 表单验证规则
const rules = {
  roleName: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
  roleCode: [{ required: true, message: '请输入角色编码', trigger: 'blur' }],
  description: [{ required: false, message: '请输入角色描述', trigger: 'blur' }]
}

// 响应式变量
const tableData = ref<RoleItem[]>([])
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
const form = ref<RoleItem>({ ...{ roleName: '', roleCode: '', description: '' } })
const queryForm = ref({ roleName: '', page: 1, limit: 10 })

// 权限操作相关变量
const permissionDrawerVisible = ref(false)
const permissionAction = ref<'assign' | 'unbind'>('assign')
const permissionLoading = ref(false)
const permissionTreeRef = ref()
const permissionTreeData = ref<PermissionItem[]>([])
const defaultCheckedKeys = ref<number[]>([])
const currentSelectedPermissionIds = ref<number[]>([])
const currentRoleId = ref<number | undefined>(undefined)
const currentRolePermissionId = ref<number | undefined>(undefined)

// 树形控件属性配置
const treeProps = {
  label: 'permName',
  children: 'children'
}

/**
 * 构建树形结构
 */
const buildTree = (data: PermissionItem[]): PermissionItem[] => {
  const map = new Map<number, PermissionItem>()
  const roots: PermissionItem[] = []

  data.forEach((item) => {
    map.set(item.id, { ...item, children: [] })
  })

  data.forEach((item) => {
    const node = map.get(item.id)
    if (node) {
      if (item.parentId === 0) {
        roots.push(node)
      } else {
        const parent = map.get(item.parentId)
        if (parent) {
          parent.children!.push(node)
          parent.hasChildren = true
        }
      }
    }
  })

  return roots
}

/**
 * 获取角色列表数据
 */
const getList = async () => {
  try {
    const res = await fetchList({
      page: currentPage.value,
      limit: pageSize.value,
      roleName: queryForm.value.roleName
    })
    tableData.value = res.data.list
    total.value = res.data.total
  } catch {
    ElMessage.error('获取角色列表失败')
  }
}

/**
 * 获取权限列表数据并构建树形结构
 */
const getPermissionList = async () => {
  if (!currentRoleId.value) return

  try {
    // 重置状态
    permissionTreeData.value = []
    defaultCheckedKeys.value = []
    currentSelectedPermissionIds.value = []

    // 获取所有权限
    const res = await fetchPermissionList({ limit: 999, page: 1 })
    const permissionList = res.data?.list || res.data || []

    // 获取当前角色已有权限
    const rolePermRes = await getOneRolePermission(currentRoleId.value)
    const rolePermissions = rolePermRes.data || []
    const existingPermIds = rolePermissions.map((item: any) => item.permId).filter(Boolean)

    // 处理权限数据
    const processedData = permissionList.map((item: any) => {
      return {
        id: item.id,
        permName: item.permName || item.permissionName || item.name || `权限${item.id}`,
        permCode: item.permCode || '',
        permType: item.permType || 1,
        parentId: item.parentId || 0,
        description: item.description || '',
        path: item.path || '',
        component: item.component || '',
        icon: item.icon || '',
        children: [],
        isBound: false, // 先设置为false，后面会重新计算
        disabled: false // 先设置为false，后面会重新计算
      }
    })

    // 构建树形结构
    permissionTreeData.value = buildTree(processedData)

    // 递归设置权限的绑定状态和禁用状态
    setPermissionStatus(permissionTreeData.value, existingPermIds)

    // 设置默认选中项（解绑操作时默认选中所有已绑定项）
    if (permissionAction.value === 'unbind') {
      const allBoundIds = getAllBoundPermissionIds(permissionTreeData.value)
      defaultCheckedKeys.value = allBoundIds
      currentSelectedPermissionIds.value = [...allBoundIds]
    }

    await nextTick()
    permissionTreeRef.value?.setCheckedKeys(defaultCheckedKeys.value)
  } catch (error) {
    console.error('获取权限列表失败:', error)
    ElMessage.error('获取权限列表失败')
  }
}

/**
 * 递归设置权限的绑定状态和禁用状态
 */
const setPermissionStatus = (permissions: PermissionItem[], existingPermIds: number[]) => {
  permissions.forEach((permission) => {
    // 先处理子权限
    if (permission.children && permission.children.length > 0) {
      setPermissionStatus(permission.children, existingPermIds)
    }

    // 计算当前权限的绑定状态
    const isDirectlyBound = existingPermIds.includes(permission.id)
    const allChildrenBound = areAllChildrenBound(permission, existingPermIds)

    // 如果直接绑定或所有子权限都已绑定，则认为该权限已绑定
    permission.isBound = isDirectlyBound || allChildrenBound

    // 设置禁用状态
    if (permissionAction.value === 'assign') {
      // 绑定操作：已绑定的权限禁用
      permission.disabled = permission.isBound
    } else {
      // 解绑操作：未绑定的权限禁用
      permission.disabled = !permission.isBound
    }
  })
}

/**
 * 检查权限的所有子权限是否都已绑定
 */
const areAllChildrenBound = (permission: PermissionItem, existingPermIds: number[]): boolean => {
  if (!permission.children || permission.children.length === 0) {
    return false
  }

  return permission.children.every((child) => {
    const isChildBound = existingPermIds.includes(child.id)
    const childrenAllBound = areAllChildrenBound(child, existingPermIds)
    return isChildBound || childrenAllBound
  })
}

/**
 * 获取所有已绑定的权限ID
 */
const getAllBoundPermissionIds = (permissions: PermissionItem[]): number[] => {
  const boundIds: number[] = []

  const collectBoundIds = (perms: PermissionItem[]) => {
    perms.forEach((perm) => {
      if (perm.isBound) {
        boundIds.push(perm.id)
      }
      if (perm.children && perm.children.length > 0) {
        collectBoundIds(perm.children)
      }
    })
  }

  collectBoundIds(permissions)
  return boundIds
}

/**
 * 处理权限树勾选状态变化
 */
const handlePermissionTreeCheck = () => {
  if (!permissionTreeRef.value) return

  // 只获取实际勾选的权限ID
  const checkedKeys = permissionTreeRef.value.getCheckedKeys() as number[]

  // 不再自动收集子权限，只传递实际勾选的权限
  currentSelectedPermissionIds.value = checkedKeys
}

// 可以删除或注释掉这个方法，因为不再需要自动收集子权限
/*
const getPermissionIdsWithChildren = (selectedIds: number[]): number[] => {
  const allSelectedIds = new Set(selectedIds)
  const resultIds = new Set<number>()

  const collectPermissionIds = (permissionData: PermissionItem[]) => {
    permissionData.forEach((permission) => {
      if (allSelectedIds.has(permission.id)) {
        resultIds.add(permission.id)

        // 递归收集所有子权限
        if (permission.children && permission.children.length > 0) {
          const collectAllChildren = (children: PermissionItem[]) => {
            children.forEach((child) => {
              resultIds.add(child.id)
              if (child.children && child.children.length > 0) {
                collectAllChildren(child.children)
              }
            })
          }
          collectAllChildren(permission.children)
        }
      }

      // 继续处理子权限
      if (permission.children && permission.children.length > 0) {
        collectPermissionIds(permission.children)
      }
    })
  }

  collectPermissionIds(permissionTreeData.value)
  return Array.from(resultIds)
}
*/

/**
 * 分页相关方法
 */
const handleSizeChange = (val: number) => {
  pageSize.value = val
  getList()
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
  getList()
}

/**
 * 查询和重置
 */
const handleQuery = () => {
  currentPage.value = 1
  getList()
}

const resetQuery = () => {
  queryForm.value = { roleName: '', page: 1, limit: 10 }
  currentPage.value = 1
  getList()
}

/**
 * 角色新增/编辑/删除
 */
const handleAdd = () => {
  form.value = { roleName: '', roleCode: '', description: '' }
  dialogType.value = 'add'
  dialogVisible.value = true
}

const handleEdit = (row: RoleItem) => {
  form.value = { ...row }
  dialogType.value = 'edit'
  dialogVisible.value = true
}

const handleDelete = (row: RoleItem) => {
  if (!row.id) return

  ElMessageBox.confirm('确认删除该角色吗？', '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      try {
        await deleteRole(row.id)
        ElMessage.success('删除成功')
        getList()
      } catch {
        ElMessage.error('删除失败')
      }
    })
    .catch(() => {})
}

const handleSubmit = async () => {
  if (!formRef.value) return

  await formRef.value.validate(async (valid) => {
    if (!valid) return

    try {
      if (dialogType.value === 'add') {
        await createRole(form.value)
        ElMessage.success('添加成功')
      } else {
        await updateRole(form.value)
        ElMessage.success('更新成功')
      }

      dialogVisible.value = false
      getList()
    } catch {
      ElMessage.error(dialogType.value === 'add' ? '添加失败' : '更新失败')
    }
  })
}

/**
 * 权限操作相关方法
 */
const handlePermissionAction = async (row: RoleItem, action: 'assign' | 'unbind') => {
  if (!row.id) return

  currentRoleId.value = row.id
  permissionAction.value = action
  permissionDrawerVisible.value = true
  permissionLoading.value = true

  await nextTick()
  await getPermissionList()

  permissionLoading.value = false
}

const handleConfirmPermissionAction = async () => {
  if (!permissionTreeRef.value || !currentRoleId.value) return

  permissionLoading.value = true

  try {
    if (permissionAction.value === 'assign') {
      // 绑定权限逻辑
      const requestData: RolePermissionData = {
        roleId: currentRoleId.value,
        permissionIds: currentSelectedPermissionIds.value
      }

      if (currentRolePermissionId.value) {
        requestData.id = currentRolePermissionId.value
        await updateRolePermission(requestData)
        ElMessage.success('更新权限成功')
      } else {
        await createRolePermission(requestData)
        ElMessage.success('绑定权限成功')
      }
    } else {
      // 解绑权限逻辑
      if (currentSelectedPermissionIds.value.length === 0) {
        ElMessage.warning('请选择要解绑的权限')
        return
      }

      // 获取要解绑的权限ID
      const { data: currentRolePermissions } = await getOneRolePermission(currentRoleId.value)
      const targetPermissionIds = currentRolePermissions
        .filter((item: any) => currentSelectedPermissionIds.value.includes(item.permId))
        .map((item: any) => item.id)
        .filter(Boolean)

      await deleteRolePermission({ ids: targetPermissionIds })
      ElMessage.success('解绑权限成功')
    }

    permissionDrawerVisible.value = false

    // 检查当前用户是否为操作角色，如是则刷新页面
    if (userStore.roles.some((role) => role === getCurrentRoleName(currentRoleId.value))) {
      setTimeout(() => window.location.reload(), 1000)
    }

    // 重置状态
    currentRoleId.value = undefined
    currentRolePermissionId.value = undefined
    currentSelectedPermissionIds.value = []
  } catch (error) {
    console.error('权限操作失败:', error)
    ElMessage.error(permissionAction.value === 'assign' ? '绑定权限失败' : '解绑权限失败')
  } finally {
    permissionLoading.value = false
  }
}

/**
 * 根据角色ID获取角色名称
 */
const getCurrentRoleName = (roleId: number): string => {
  const role = tableData.value.find((item) => item.id === roleId)
  return role?.roleName || ''
}

// 初始化
onMounted(() => {
  if (userStore.token) {
    getList()
  }
})

// 暴露方法
defineExpose({ getList })
</script>

<style lang="scss" scoped>
:deep(.el-form-item__content) {
  @apply w-64;
}

:deep(.el-drawer__body) {
  @apply p-6;
}

.permission-tree {
  :deep(.el-tree-node__content) {
    height: auto;
    padding: 8px 0;
    border-radius: 4px;
    transition: all 0.2s ease;
    
    &:hover {
      background-color: #f5f7fa;
    }
  }

  :deep(.el-tree-node__label) {
    flex: 1;
    width: 100%;
  }

  // 树节点内容样式
  .tree-node-content {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 8px;
    padding: 4px 8px;
    border-radius: 4px;
    transition: all 0.2s ease;
    
    // 禁用状态
    &.is-disabled {
      opacity: 0.6;
      background-color: #f8f9fa;
      
      .node-label {
        color: #c0c4cc;
        text-decoration: line-through;
      }
      
      .node-icon {
        opacity: 0.5;
      }
    }
    
    // 已绑定状态
    &.is-bound {
      background-color: #f0f9ff;
      border-left: 3px solid #3b82f6;
    }
  }

  // 图标样式
  .node-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    
    .menu-icon {
      color: #3b82f6;
      font-size: 16px;
    }
    
    .button-icon {
      color: #10b981;
      font-size: 14px;
    }
  }

  // 权限名称样式
  .node-label {
    flex: 1;
    font-size: 14px;
    color: #374151;
    font-weight: 500;
    
    .is-disabled & {
      color: #9ca3af;
    }
  }

  // 标签区域样式
  .node-tags {
    display: flex;
    align-items: center;
    gap: 6px;
    
    .type-tag {
      font-size: 11px;
      padding: 2px 6px;
      border-radius: 10px;
    }
    
    .status-tag {
      font-size: 10px;
      padding: 1px 4px;
      border-radius: 8px;
      opacity: 0.8;
    }
  }

  // 响应式设计
  @media (max-width: 768px) {
    .tree-node-content {
      flex-direction: column;
      align-items: flex-start;
      gap: 4px;
      
      .node-tags {
        align-self: flex-end;
      }
    }
  }
}

// 抽屉样式优化
:deep(.el-drawer__body) {
  padding: 20px;
  background-color: #fafbfc;
}

// 辅助样式类
.text-gray-600 {
  color: #6b7280;
}

.text-blue-500 {
  color: #3b82f6;
}

.text-green-500 {
  color: #10b981;
}
</style>
